﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.XPath;
using EpiNEXT.Core.Collections;
using EpiNEXT.Core.Fields;

namespace EpiNEXT.Core
{
    [Serializable()]
    public class Form : DataEntryInstrument
    {
        #region Members
        private static object _pagesLock = new object();
        #endregion // Members

        #region Properties
        /// <summary>
        /// A description of the form
        /// </summary>
        [XmlElement("Description")]
        public string Description { get; set; }

        /// <summary>
        /// A list of pages in the form
        /// </summary>
        [XmlArray("Pages")]
        [XmlArrayItem("Page", typeof(Page))]  
        public ObservableCollection<Page> Pages { get; set; }

        [XmlIgnore]
        public int Version { get; set; }

        [XmlElement]
        public double PageWidth { get; set; }

        [XmlElement]
        public double PageHeight { get; set; }

        [XmlElement]
        public double PageMarginTop { get; set; }

        [XmlElement]
        public double PageMarginLeft { get; set; }
        #endregion // Properties

        #region Constructors
        /// <summary>
        /// Constructor
        /// </summary>
        [Obsolete("Use of default constructor not allowed", true)]
        private Form() { }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="owner">The project that owns this form</param>
        public Form(Project owner) : base()
        {
            this.DateCreated = DateTime.Now;
            this.DateLastSaved = DateTime.Now;
            this.Title = "New Form";
            this.Description = String.Empty;
            this.FormId = Guid.NewGuid();
            this.Owner = owner;
            this.FieldsDTO = new FieldsDTO();
            this.Pages = new ObservableCollection<Page>();
        }
        #endregion // Constructors

        #region Methods
        public Page GetPageById(Guid id)
        {
            foreach (Page page in this.Pages)
            {
                if (page.PageId.Equals(id))
                {
                    return page;
                }
            }
            throw new InvalidOperationException("Requested page does not exist.");
        }

        /// <summary>
        /// Gets the next page position
        /// </summary>
        /// <returns>int; represents the page position</returns>
        public int GetNextPagePosition()
        {
            int nextPosition = 0;
            foreach (Page page in this.Pages)
            {
                if (page.Position > nextPosition)
                {
                    nextPosition = page.Position;
                }
            }

            return nextPosition;
        }

        /// <summary>
        /// Sets a special binding operation to the form's collection so that the collections can be accessed
        /// on a thread other than the UI thread.
        /// </summary>
        public override void InitalizeCollectionSynchronization()
        {
            base.InitalizeCollectionSynchronization();

            System.Windows.Data.BindingOperations.EnableCollectionSynchronization(Pages, _pagesLock);
        }
        #endregion // Methods
    }
}
